home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / ddjgrep.zip / GREP.C < prev    next >
Text File  |  1987-11-04  |  9KB  |  332 lines

  1. /*---------------------------------------------------------------------------
  2.  *           GREP.C    a generalized regular expression parser 
  3.  *
  4.  *
  5.  *                Copyright (c) 1984 Allen Holub
  6.  *      Copyright (c) 1984 Software Engineering Consultants
  7.  *                      P.O. Box 5679
  8.  *                   Berkeley, CA.  94705
  9.  *
  10.  *                     All rights reserved.
  11.  *
  12.  *      This program may be copied for personal, non-commmercial use
  13.  *      only, provided that this copyright notice is included in all
  14.  *      copies and that this program is not modified in any way.
  15.  *      Copying for any other use without previously obtaining the 
  16.  *      written permission of the author is prohibited.
  17.  *
  18.  *---------------------------------------------------------------------------
  19.  */
  20.  
  21. /* 
  22.  *      The algorithm used here is essentially the algorithm in
  23.  *      Software Tools in Pascal (pp 145f.). Though the routines have  
  24.  *      been changed somewhat to put them into good 'C'.
  25.  *
  26.  *      This program is a healthy subset of the UNIX program of the same
  27.  *      name. The differences are as follows:
  28.  *
  29.  *              - the -s, -x, and -b options are not supported.
  30.  *              - the meta-characters ()+? are not supported.
  31.  *
  32.  *      usage is:
  33.  *              grep [-vclnhyef] [expression] files ...
  34.  *
  35.  */
  36.  
  37. #include <stdio.h>
  38. #include <ctype.h>
  39. #include <malloc.h>
  40. #include <string.h>
  41. #include "tools.h"
  42.  
  43. #define MAXLINE 128             /* Maximum size of an input line        */
  44.  
  45. #define MAX_EXPR 64             /* Maximum number of regular expressions 
  46.                                  * seperated by newlines or |  allowed
  47.                                  */
  48. /*      The following global flags are true if a switch was set
  49.  *      on the command line, false otherwise.
  50.  */
  51.  
  52. int     vflag, yflag, cflag, lflag, nflag, hflag, fflag;
  53.  
  54. main(argc,argv)
  55. int     argc;
  56. char    **argv;
  57. {
  58.         int     i, j, linenum, count;
  59.         int     line[MAXLINE];
  60.         int     numfiles;
  61.         FILE    *stream;
  62.         int     exprc;
  63.  
  64.         TOKEN   *exprv[MAX_EXPR];
  65.  
  66.         i = 1;
  67.  
  68.         if (argc < 2)
  69.                 abort(pr_usage(1));
  70.  
  71.         if (*argv[i] == '-')            /* command line switches ? */
  72.         {
  73.                 expand_sw (argv[i++]);
  74.  
  75.                 if ( i == argc )
  76.                         abort(pr_usage(1));
  77.         }
  78.  
  79.         /*      Pattern string          */
  80.  
  81.         if ((exprc = get_expr(exprv, MAX_EXPR, &argv[i++])) == 0)
  82.                 abort (pr_usage(2));
  83.  
  84.         numfiles = argc - i;            /* number of files left to process  */
  85.  
  86.         fprintf(stderr,"                          \n");  /* opening message */
  87.         do
  88.         {
  89.                 if (numfiles)
  90.                 {
  91.                         stream = fopen(argv[i],"r");
  92.                         if (stream == NULL)
  93.                         {
  94.                                 fprintf(stderr,"Can't open %s\n", argv[i]);
  95.                                 continue;
  96.                         }
  97.                 }
  98.                 else 
  99.                         stream = stdin;
  100.  
  101.                 count = 0;
  102.                 linenum = 1;
  103.  
  104.                 while (fgets(line, MAXLINE, stream))
  105.                 {
  106.                         if (yflag)              /* MSC routine instead of */
  107.                                 strupr(line);   /* stoupper in tools.c    */   
  108.  
  109.                         for (j = exprc; --j >= 0;)
  110.                         {
  111.                              if (matchs(line,exprv[j]))
  112.                              {
  113.                                   count++;
  114.                                    pr_match(linenum,line,argv[i],1,numfiles);
  115.                              }
  116.                              else  pr_match(linenum,line,argv[i],0,numfiles);
  117.                              linenum++;
  118.                         }
  119.                         if (lflag && count)     break;
  120.                 }
  121.                 pr_count(numfiles,argv[i],count);
  122.                 fclose(stream);
  123.         } while (++i < argc);
  124.         abort();
  125. }
  126.  
  127. /* ----------------------------------------------------------------------- */
  128.  
  129. pr_count (fcount,fname,count)
  130. int     fcount, count;
  131. char    *fname;
  132. {
  133.         if (!cflag) 
  134.                 return;
  135.         if (fcount > 1)
  136.                 printf("%-12s: ",fname);
  137.         printf("%d\n", count);
  138. }
  139.  
  140. /* ----------------------------------------------------------------------- */
  141.  
  142. pr_match (linenum, line, fname, match, numfiles)
  143. int     linenum, match, numfiles;
  144. char    *line, *fname;
  145. {
  146.         char    buf[80];
  147.  
  148.         if (cflag)
  149.                 return;
  150.         if ((vflag && !match) || (!vflag && match))
  151.         {
  152.                 if (!hflag && ((numfiles > 1) || lflag))
  153.                         printf("%s%s",fname,lflag ? "\n" : ":" );
  154.                 if (nflag)
  155.                         printf("%03d:",linenum);
  156.                 if (!lflag)
  157.                         printf("%s",line);
  158.         }
  159. }
  160.  
  161. /* ----------------------------------------------------------------------- */
  162.  
  163. pr_usage (num)
  164. int     num;
  165. {
  166. #ifdef DEBUG
  167.         fprintf(stderr,"%d ", num);
  168. #endif
  169.         fprintf(stderr,"usage: grep [-cefhlnvy] [expression] <files...>\n");
  170. }
  171.  
  172. /* ----------------------------------------------------------------------- */
  173.  
  174. abort()
  175. {
  176.         exit();
  177. }
  178.  
  179. /* ----------------------------------------------------------------------- */
  180.  
  181. expand_sw(str)
  182. char    *str;
  183. {
  184.         vflag = 0;
  185.         cflag = 0;
  186.         lflag = 0;
  187.         nflag = 0;
  188.         hflag = 0;
  189.         fflag = 0;
  190.         yflag = 0;
  191.  
  192.         while (*str)
  193.         {
  194.                 switch (toupper(*str))
  195.                 {
  196.                 case '-':
  197.                 case 'E':
  198.                         break;
  199.                 case 'C':
  200.                         cflag = 1;
  201.                         break;
  202.                 case 'F':
  203.                         fflag = 1;
  204.                         break;
  205.                 case 'H':
  206.                         hflag = 1;
  207.                         break;
  208.                 case 'L':
  209.                         lflag = 1;
  210.                         break;
  211.                 case 'N':
  212.                         nflag = 1;
  213.                         break;
  214.                 case 'V':
  215.                         vflag = 1;
  216.                         break;
  217.                 case 'Y':
  218.                         yflag = 1;
  219.                         break;
  220.                 default:
  221.                         pr_usage(3);
  222.                         abort();
  223.                         break;
  224.                 }
  225.                 str++;
  226.         }
  227. }
  228.  
  229. /* ----------------------------------------------------------------------- */
  230.  
  231. int do_or( lp, expr, max )
  232. char    *lp;
  233. TOKEN   **expr;
  234. int     max;
  235. {
  236.         int     found;
  237.         TOKEN   *pat;
  238.         char    *op;
  239.  
  240.         found = 0;
  241.  
  242.         /* 
  243.          *      Extract regular expressions seperated by OR_SYM's from
  244.          *      lp and put them into expr. Extract only up to max 
  245.          *      expressions. If yflag is true map string to uppercase first
  246.          */
  247.  
  248.  
  249.         if (yflag) 
  250.                 strupr(lp);
  251.  
  252.         while (op = in_string(OR_SYM, lp))
  253.         {
  254.                 if (found <= max && (pat = makepat(lp,OR_SYM)))
  255.                 {
  256.                         *expr++ = pat;
  257.                         found++;
  258.                 }
  259.                 lp = ++op;
  260.                 if (pat == 0)
  261.                         goto fatal_err;
  262.         }
  263.  
  264.         if (found <= max && (pat = makepat(lp,OR_SYM)))
  265.         {
  266.                 found++;
  267.                 *expr = pat;
  268.         }
  269.  
  270.         if (pat == 0)
  271.         {
  272. fatal_err:
  273.                 printf("Illegal expression\n");
  274.                 exit();
  275.         }
  276.         return (found);
  277. }
  278.  
  279. /* ----------------------------------------------------------------------- */
  280.  
  281. get_expr (expr, max, defexpr)
  282. TOKEN   *expr[];
  283. int     max;
  284. char    **defexpr;
  285. {
  286.         FILE    *stream;
  287.         int     count;
  288.         char    line[MAXLINE];
  289.  
  290. #ifdef DEBUG
  291.         int     i;
  292. #endif
  293.         /*      Get regular expressions seperated by | or newlines either
  294.          *      out of a file or off the command line depending on whether
  295.          *      the -f flag is set. The expressions are converted into 
  296.          *      p